﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Collections.Generic;
using System.Linq;
using SuperDeepZoom;
using System.Windows.Browser;
using eventr.Model;
using System.Collections.ObjectModel;
using System.Windows.Threading;

namespace eventr.View
{
    /// <summary>
    /// This is an example of how you might like to control the SuperDeepZoom in your app. 
    /// This class manages the image data for the overlays, coordinates user operations and filtering
    /// </summary>
    public class MainPageViewModel : ViewModel
    {
        int? viewedImage = null;

        List<ImageMetaData> subImageMetadata;

        List<FlyThroughOverlaySegment> flyThroughOverlaySegments;

        List<string> allTags;

        List<int> filterIds = new List<int>();

        bool flyThroughOverlayEnabled = false;
        bool showFlyThoughInfoPopup = false;
        bool mostViewedMode = false;
        bool specialImageOverlayEnabled = false;

        SuperDeepZoom.SuperDeepZoom zoom;

        string filterTag;
        string flyThroughHash;
        string deepZoomSource;

        ImageMetaData currentImageContext = null;

        Dictionary<int, object> imageContextData;

        public MainPageViewModel(SuperDeepZoom.SuperDeepZoom zoom)
        {
            ImageViewManager ivm = new ImageViewManager();
            ivm.DataLoaded += new EventHandler(ivm_DataLoaded);

            Uri i = new Uri(HtmlPage.Document.DocumentUri, "ImageData.xml");

            ivm.DownloadData(i);

            //

            this.zoom = zoom;
            zoom.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(zoom_PropertyChanged);
            SpecialImageOverlayEnabled = true;
        }

        void ivm_DataLoaded(object sender, EventArgs e)
        {
            ImageViewManager ivm = sender as ImageViewManager;
            ImageDataLoaded(ivm.MetaData);
        }


        /// <summary>
        /// When the image data is retrived from the server. SDZ control does not have any 
        /// hard coded "data gathering" it must all be passed in for maximum flexibility.
        /// </summary>
        /// <param name="images"></param>
        public void ImageDataLoaded(List<ImageMetaData> images)
        {
            List<string> result = new List<string>();
            imageContextData = new Dictionary<int, object>();
            foreach (var p in images)
            {

                imageContextData.Add(p.Id, p);

                if (!result.Contains(p.Tag))
                {
                    result.Add(p.Tag);
                }
            }

            subImageMetadata = images;
            AllTags = result;

            OnPropertyChanged("ImageContextData");
        }

        /// <summary>
        /// User has selected a new filter, build a filter list and pass to the SDZ through binding (by 
        /// raising property change event)
        /// </summary>
        void updateFilter()
        {
            filterIds = new List<int>();

            string tag = FilterTag;

            if (tag != "All")
            {
                foreach (var i in subImageMetadata)
                {
                    if (i.Tag == FilterTag)
                    {
                        filterIds.Add(i.Id);
                    }
                }
            }

            OnPropertyChanged("FilterIds");
        }

        void updatedViewedOverlay()
        {
            subImageMetadata.ForEach(p => p.Viewed = false);

            if (viewedImage != null && viewedImage.HasValue)
            {
                var sim = subImageMetadata.FirstOrDefault(p => p.Id == viewedImage.Value);
                if (sim != null)
                {
                    sim.Viewed = true;
                }
            }
        }


        public SuperDeepZoom.SuperDeepZoom SuperDeepZoom
        {
            get
            {
                return zoom;
            }
        }

        /// <summary>
        /// Show the image overlays with image count in them (actual overlay content
        /// can be altered through templates)
        /// </summary>
        public bool SpecialImageOverlayEnabled
        {
            get
            {
                return specialImageOverlayEnabled;
            }
            set
            {
                specialImageOverlayEnabled = value;
                OnPropertyChanged("SpecialImageOverlayEnabled");
            }
        }

        /// <summary>
        /// Provides image context data for the SDZ control, image 
        /// data is retrieved from the WCF service (could get it 
        /// from any data source you like). Nothing is hard coded
        /// in the SDZ control
        /// </summary>
        public Dictionary<int, object> ImageContextData
        {
            get
            {
                return imageContextData;
            }
            set
            {
                imageContextData = value;
                OnPropertyChanged("ImageContextData");
            }
        }

        /// <summary>
        /// The current list of sub images to show.
        /// </summary>
        public List<int> FilterIds
        {
            get
            {
                return filterIds;
            }
            set
            {
                filterIds = value;
                OnPropertyChanged("FilterIds");
            }
        }

        public string DeepZoomSource
        {
            get
            {
                return deepZoomSource;
            }
            set
            {
                deepZoomSource = value;
                OnPropertyChanged("DeepZoomSource");
            }
        }

        /// <summary>
        /// The image data context for the current image, used to show the 
        /// extra information popup at the bottom of the screen when zoomed in 
        /// on an image
        /// 
        /// </summary>
        public ImageMetaData CurrentImageContext
        {
            get
            {
                return currentImageContext;
            }
            set
            {
                currentImageContext = value;
                OnPropertyChanged("CurrentImageContext");
            }
        }

        /// <summary>
        /// The ID of the currnelty viewed image, retrieved through binding from 
        /// the SDZ
        /// </summary>
        public int? ViewedImage
        {
            get
            {
                return viewedImage;
            }
            set
            {
                viewedImage = value;

                OnPropertyChanged("CurrentImageHash");
                OnPropertyChanged("CurrentImageContext");
                OnPropertyChanged("ViewedImage");

                updatedViewedOverlay();
            }
        }

        /// <summary>
        /// The list of metdata for each image in the collection
        /// 
        /// </summary>
        public List<ImageMetaData> SubImageMetadata
        {
            get
            {
                return subImageMetadata;
            }
            set
            {
                subImageMetadata = value;
                OnPropertyChanged("SubImageMetadata");
            }
        }

        public string FilterTag
        {
            get
            {
                return filterTag;
            }
            set
            {
                filterTag = value;
                updateFilter();
                OnPropertyChanged("FilterTag");
            }
        }

        /// <summary>
        /// The filter id's i.e. AAA, BBB etc. You can make your own lists.
        /// </summary>
        public List<string> AllTags
        {
            get
            {
                return allTags;
            }
            set
            {
                allTags = value;
                allTags.Insert(0, "All");
                OnPropertyChanged("AllTags");
            }
        }

        /// <summary>
        /// Provides a URL that can be copied and pasted to transfer the current
        /// Flythrough can be copied to another browser window
        /// </summary>
        public string FlyThroughHash
        {
            get
            {
                string deepLink = HtmlPage.Document.DocumentUri.ToString();

                if (deepLink.IndexOf("#") != -1)
                {
                    deepLink = deepLink.Substring(0, deepLink.IndexOf("#"));
                }

                deepLink += "#" + flyThroughHash;

                return deepLink;
            }
            set
            {
                flyThroughHash = value;
                OnPropertyChanged("FlyThroughHash");
            }
        }

        /// <summary>
        /// Gets the hash link for the current image in the collection
        /// </summary>
        public string CurrentImageHash
        {
            get
            {
                if (ViewedImage != null && ViewedImage.HasValue)
                {
                    string deepLink = HtmlPage.Document.DocumentUri.ToString();

                    if (deepLink.IndexOf("#") != -1)
                    {
                        deepLink = deepLink.Substring(0, deepLink.IndexOf("#"));
                    }

                    deepLink += "#" + ViewedImage.Value.ToString();
                    return deepLink;
                }
                else
                {
                    return null;
                }
            }
        }

        /// <summary>
        /// The fly through overlay segments which are applied to the fly through. 
        /// </summary>
        public List<FlyThroughOverlaySegment> FlyThroughOverlaySegments
        {
            get
            {
                return flyThroughOverlaySegments;
            }
            set
            {
                flyThroughOverlaySegments = value;
                OnPropertyChanged("FlyThroughOverlaySegments");
            }
        }

        public bool FlyThroughOverlayEnabled
        {
            get
            {
                return flyThroughOverlayEnabled;
            }
            set
            {
                flyThroughOverlayEnabled = value;
                OnPropertyChanged("FlyThroughOverlayEnabled");
            }
        }

        public bool ShowFlyThoughInfoPopup
        {
            get
            {
                return showFlyThoughInfoPopup;
            }
            set
            {
                showFlyThoughInfoPopup = value;
                FlyThroughOverlayEnabled = true;
                OnPropertyChanged("ShowFlyThoughInfoPopup");
            }
        }

        void zoom_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            switch (e.PropertyName)
            {
                case "FlyThroughHash":
                    FlyThroughHash = zoom.FlyThroughHash;
                    break;
                case "ViewedImage":
                    ViewedImage = zoom.ViewedImage;
                    break;
                case "HasUrlFlyThrough":
                    ShowFlyThoughInfoPopup = zoom.HasUrlFlyThrough;
                    break;
                case "CurrentImageContext":
                    CurrentImageContext = zoom.CurrentImageContext as ImageMetaData;
                    break;
            }
        }

    }
}
